/**
 * @file uart_protocol.c
 * @brief 串口通信协议模块实现
 * @version 1.0
 * @date 2023-03-15
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "uart_protocol.h"
#include "system_utils.h"

// 最大负载大小定义
#define MAX_PAYLOAD_SIZE 128

// 使用extern引用在uart_handler.c中定义的全局变量
extern const uint8_t FRAME_HEADER[2];
extern const uint8_t FRAME_FOOTER[2];

// 验证请求帧
bool validate_request_frame(const RequestFrame *frame) {
    if (!frame) {
        return false;
    }
    
    // 检查帧头
    if (frame->header[0] != FRAME_HEADER[0] || frame->header[1] != FRAME_HEADER[1]) {
        log_message(LOG_LEVEL_DEBUG, "UART协议: 请求帧头不匹配");
        return false;
    }
    
    // 检查命令类型 - 使用正确的命令常量
    if (memcmp(frame->cmd, CMD_REQUEST, 2) != 0) {
        log_message(LOG_LEVEL_DEBUG, "UART协议: 请求命令类型无效(%c%c)", 
                   frame->cmd[0], frame->cmd[1]);
        return false;
    }
    
    // 检查帧尾
    if (frame->footer[0] != FRAME_FOOTER[0] || frame->footer[1] != FRAME_FOOTER[1]) {
        log_message(LOG_LEVEL_DEBUG, "UART协议: 请求帧尾不匹配");
        return false;
    }
    
    // 检查数据长度
    if (frame->data_length > 32) {
        log_message(LOG_LEVEL_DEBUG, "UART协议: 请求数据长度无效(%d)", frame->data_length);
        return false;
    }
    
    // 计算校验和
    uint8_t calc_checksum = calculate_checksum(frame, sizeof(RequestFrame) - 3);
    if (calc_checksum != frame->checksum) {
        log_message(LOG_LEVEL_DEBUG, "UART协议: 请求校验和错误(接收=%02X, 计算=%02X)", 
                  frame->checksum, calc_checksum);
        return false;
    }
    
    return true;
}

// 验证响应帧
bool validate_response_frame(const ResponseFrame *frame, size_t length) {
    if (!frame || length < sizeof(ResponseFrame)) {
        return false;
    }
    
    // 检查帧头
    if (frame->header[0] != FRAME_HEADER[0] || frame->header[1] != FRAME_HEADER[1]) {
        log_message(LOG_LEVEL_DEBUG, "UART协议: 响应帧头不匹配");
        return false;
    }
    
    // 检查命令类型 - 使用正确的命令常量
    if (memcmp(frame->cmd, CMD_RESPONSE, 2) != 0) {
        log_message(LOG_LEVEL_DEBUG, "UART协议: 响应命令类型无效(%c%c)", 
                   frame->cmd[0], frame->cmd[1]);
        return false;
    }
    
    // 验证数据长度
    if (frame->data_length > MAX_PAYLOAD_SIZE) {
        log_message(LOG_LEVEL_DEBUG, "UART协议: 响应数据长度无效(%d)", frame->data_length);
        return false;
    }
    
    // 确保完整的响应帧在buffer中
    size_t expected_length = offsetof(ResponseFrame, data) + frame->data_length + 1 + 2; // 头部 + 数据 + 校验和 + 帧尾
    if (length < expected_length) {
        log_message(LOG_LEVEL_DEBUG, "UART协议: 响应数据不完整(接收=%d, 需要=%d)", 
                  (int)length, (int)expected_length);
        return false;
    }
    
    // 计算校验和
    uint8_t calc_checksum = calculate_checksum(frame, sizeof(ResponseFrame) - 3);
    
    // 获取帧中的校验和 (位于data后)
    uint8_t frame_checksum = frame->data[frame->data_length];
    
    if (frame_checksum != calc_checksum) {
        log_message(LOG_LEVEL_DEBUG, "UART协议: 响应校验和错误(接收=%02X, 计算=%02X)", 
                  frame_checksum, calc_checksum);
        return false;
    }
    
    // 检查帧尾 (位于checksum后) - 修复const限定符问题
    const uint8_t *frame_footer = &frame->data[frame->data_length + 1];
    if (frame_footer[0] != FRAME_FOOTER[0] || frame_footer[1] != FRAME_FOOTER[1]) {
        log_message(LOG_LEVEL_DEBUG, "UART协议: 响应帧尾不匹配");
        return false;
    }
    
    return true;
}

// 解析传感器数据包
bool parse_sensor_data_packet(const uint8_t *data, size_t length, SensorDataPacket *packet) {
    if (!data || !packet || length < sizeof(SensorDataPacket)) {
        return false;
    }
    
    // 直接复制数据
    memcpy(packet, data, sizeof(SensorDataPacket));
    
    return true;
}

// 创建请求帧
void create_request_frame(RequestFrame *frame, uint8_t command) {
    if (!frame) {
        return;
    }
    
    // 设置帧头
    frame->header[0] = FRAME_HEADER[0];
    frame->header[1] = FRAME_HEADER[1];
    
    // 设置命令类型
    frame->cmd[0] = CMD_REQUEST[0];
    frame->cmd[1] = CMD_REQUEST[1];
    
    // 设置数据长度（请求通常没有数据）
    frame->data_length = 0;
    
    // 计算校验和
    frame->checksum = calculate_checksum(frame, sizeof(RequestFrame) - 3);
    
    // 设置帧尾
    frame->footer[0] = FRAME_FOOTER[0];
    frame->footer[1] = FRAME_FOOTER[1];
}

// 创建响应帧
void create_response_frame(ResponseFrame *frame, uint8_t command, 
                          const uint8_t *payload, uint8_t payload_length) {
    if (!frame) {
        return;
    }
    
    // 检查payload大小
    if (payload_length > MAX_PAYLOAD_SIZE) {
        payload_length = MAX_PAYLOAD_SIZE;
    }
    
    // 设置帧头
    frame->header[0] = FRAME_HEADER[0];
    frame->header[1] = FRAME_HEADER[1];
    
    // 设置命令类型
    frame->cmd[0] = CMD_RESPONSE[0];
    frame->cmd[1] = CMD_RESPONSE[1];
    
    // 设置数据长度
    frame->data_length = payload_length;
    
    // 复制载荷数据
    if (payload && payload_length > 0) {
        memcpy(frame->data, payload, payload_length);
    }
    
    // 计算校验和（包括载荷）
    frame->checksum = calculate_checksum(frame, sizeof(ResponseFrame) - 3);
    
    // 将校验和放在载荷之后
    frame->data[payload_length] = frame->checksum;
    
    // 设置帧尾（在校验和之后）
    frame->data[payload_length + 1] = FRAME_FOOTER[0];
    frame->data[payload_length + 2] = FRAME_FOOTER[1];
}

// 创建错误响应帧
void create_error_response(ResponseFrame *frame, uint8_t error_code) {
    if (!frame) {
        return;
    }
    
    uint8_t payload = error_code;
    create_response_frame(frame, CMD_ACK, &payload, 1);
}

// 获取错误码对应的字符串描述
const char* uart_error_str(int error_code) {
    switch (error_code) {
        case UART_OK:
            return "成功";
        case UART_ERR_TIMEOUT:
            return "超时错误";
        case UART_ERR_CHECKSUM:
            return "校验和错误";
        case UART_ERR_FRAME_FORMAT:
            return "帧格式错误";
        case UART_ERR_DEVICE_ERROR:
            return "设备错误";
        case UART_ERR_INVALID_PARAM:
            return "无效参数";
        case UART_ERR_LENGTH:
            return "长度错误";
        case UART_ERR_FRAME:
            return "帧错误";
        case UART_ERR_PARAM:
            return "参数错误";
        default:
            return "未知错误";
    }
} 